package xyz.hlh.boot8.service;

import com.github.tobato.fastdfs.domain.fdfs.MetaData;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.fdfs.ThumbImageConfig;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import xyz.hlh.boot8.exception.CustomException;
import xyz.hlh.boot8.util.MagicUtil;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author HLH
 * @description:
 * @email 17703595860@163.com
 * @date : Created in 2021/11/20 11:29
 */
@Service
@Slf4j
public class FileService {

    @Autowired
    private FastFileStorageClient storageClient;
    @Autowired
    private ThumbImageConfig thumbImageConfig;
    @Autowired
    private MagicUtil magicUtil;

    public InputStream download(String group, String path ) {
        return storageClient.downloadFile(group, path, ins -> ins);
    }

    public List<Map<String, Object>> uploadBatchField(MultipartFile[] files) {
        try {
            List<Map<String, Object>> listResult = new ArrayList<>();
            for (MultipartFile file : files) {
                Map<String, Object> tempMap = uploadField(file);
                listResult.add(tempMap);
            }
            return listResult;
        } catch (CustomException e) {
            e.printStackTrace();
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "文件上传失败");
        }
    }

    public Map<String, Object> uploadField(MultipartFile file) {
        try {
            String fileName = file.getOriginalFilename();
            long size = file.getSize();
            String fileSuffix = fileName.substring(fileName.lastIndexOf("."));
            // 判断后缀
            List<String> suffixList = magicUtil.getSuffixListByMagic(file);
            if (CollectionUtils.isEmpty(suffixList) || !suffixList.contains(fileSuffix)) {
                throw new CustomException(HttpStatus.BAD_REQUEST.value(), "文件类型错误");
            }
            // 判断是否是图片
            boolean imgFlg = magicUtil.isImg(fileSuffix);
            Map<String, Object> result = null;
            if (imgFlg) {
                result = uploadImgAndCreateThumb(file, fileSuffix);
            } else {
                result = uploadFile(file, fileSuffix);
            }
            if (CollectionUtils.isEmpty(result)) {
                throw new CustomException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "文件上传失败");
            }
            return result;
        } catch (CustomException e) {
            e.printStackTrace();
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "文件上传失败");
        }
    }

    private Map<String, Object> uploadFile(MultipartFile file, String fileSuffix) throws IOException {
        Set<MetaData> metadataSet = new HashSet<>();
        metadataSet.add(new MetaData("oldFieldName", file.getOriginalFilename()));
        StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), fileSuffix.substring(1), metadataSet);
        String group = storePath.getGroup();
        String filePath = storePath.getPath();
        return new HashMap<String, Object>() {{
            put("fileName", file.getOriginalFilename());
            put("group", group);
            put("filePath", filePath);
        }};
    }

    private Map<String, Object> uploadImgAndCreateThumb(MultipartFile file, String fileSuffix) throws IOException {
        Set<MetaData> metadataSet = new HashSet<>();
        metadataSet.add(new MetaData("oldFieldName", file.getOriginalFilename()));
        StorePath storePath = storageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(), fileSuffix.substring(1), metadataSet);
        String group = storePath.getGroup();
        String filePath = storePath.getPath();
        String thumbImagePath = thumbImageConfig.getThumbImagePath(storePath.getPath());
        return new HashMap<String, Object>() {{
            put("fileName", file.getOriginalFilename());
            put("group", group);
            put("filePath", filePath);
            put("thumbPath", thumbImagePath);
        }};
    }

    public String getFieldName(String group, String path, String newFileName) {
        // 获取元数据中的名字
        try {
            Set<MetaData> metadataSet = storageClient.getMetadata(group, path);
            List<MetaData> metaDataList = metadataSet.stream()
                    .filter(metaData -> "oldFieldName".equals(metaData.getName()))
                    .collect(Collectors.toList());
            if (metaDataList.size() < 1) {
                log.info("该文件没有名称，采用生成的名称");
                return path.substring(path.lastIndexOf("/") + 1);
            }
            String fieldName = metaDataList.get(0).getValue();
            return fieldName == null ? fieldName : path.substring(path.lastIndexOf("/") + 1);
        } catch (Throwable e) {
            log.info("该文件没有名称，采用生成的名称");
            return path.substring(path.lastIndexOf("/") + 1);
        }
    }

    public void deleteFile(String group, String path) {
        try {
            storageClient.deleteFile(group, path);
        } catch (Throwable e) {
            /*e.printStackTrace();*/
            log.info("文件删除失败: " + group + "/" + path);
        }
    }
}
